//package com.cragon.config;
//
//import java.io.BufferedReader;
//import java.io.InputStream;
//import java.io.InputStreamReader;
//import java.nio.charset.StandardCharsets;
//import java.util.List;
//import java.util.Map;
//import java.util.Objects;
//import lombok.Generated;
//import org.apache.catalina.Valve;
//import org.apache.catalina.authenticator.BasicAuthenticator;
//import org.apache.catalina.connector.Connector;
//import org.apache.catalina.startup.Tomcat;
//import org.apache.catalina.valves.ExtendedAccessLogValve;
//import org.apache.catalina.valves.SSLValve;
//import org.apache.catalina.valves.rewrite.RewriteValve;
//import org.apache.commons.lang3.StringUtils;
//import org.apache.coyote.http2.Http2Protocol;
//import org.apache.tomcat.util.descriptor.web.LoginConfig;
//import org.apache.tomcat.util.descriptor.web.SecurityCollection;
//import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
//import org.apereo.cas.configuration.CasConfigurationProperties;
//import org.apereo.cas.configuration.model.core.web.tomcat.CasEmbeddedApacheTomcatAjpProperties;
//import org.apereo.cas.configuration.model.core.web.tomcat.CasEmbeddedApacheTomcatBasicAuthenticationProperties;
//import org.apereo.cas.configuration.model.core.web.tomcat.CasEmbeddedApacheTomcatExtendedAccessLogProperties;
//import org.apereo.cas.configuration.model.core.web.tomcat.CasEmbeddedApacheTomcatHttpProperties;
//import org.apereo.cas.configuration.model.core.web.tomcat.CasEmbeddedApacheTomcatHttpProxyProperties;
//import org.apereo.cas.configuration.model.core.web.tomcat.CasEmbeddedApacheTomcatSslValveProperties;
//import org.apereo.cas.configuration.support.Beans;
//import org.apereo.cas.util.ResourceUtils;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.boot.autoconfigure.AutoConfigureBefore;
//import org.springframework.boot.autoconfigure.AutoConfigureOrder;
//import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
//import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
//import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
//import org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration;
//import org.springframework.boot.autoconfigure.web.ServerProperties;
//import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
//import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
//import org.springframework.boot.context.embedded.tomcat.TomcatContextCustomizer;
//import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
//import org.springframework.boot.context.properties.EnableConfigurationProperties;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.core.io.Resource;
//import org.springframework.util.SocketUtils;
//
///**
// * @Description: TODO
// * @Author: ZHOUHAILONG
// * @Date: 2020年09月17日 14:43
// */
//@Configuration("casEmbeddedContainerTomcatConfiguration")
//@EnableConfigurationProperties({CasConfigurationProperties.class})
//@ConditionalOnProperty(
//        name = {"CasEmbeddedContainerConfigurationActive"},
//        havingValue = "true"
//)
//@ConditionalOnClass({Tomcat.class, Http2Protocol.class})
//@AutoConfigureBefore({EmbeddedServletContainerAutoConfiguration.class})
//@AutoConfigureOrder(-2147483648)
//public class CasEmbeddedContainerTomcatConfiguration {
//    @Generated
//    private static final Logger LOGGER = LoggerFactory.getLogger(CasEmbeddedContainerTomcatConfiguration.class);
//    @Autowired
//    private ServerProperties serverProperties;
//    @Autowired
//    private CasConfigurationProperties casProperties;
//
//    public CasEmbeddedContainerTomcatConfiguration() {
//    }
//
//    @ConditionalOnMissingBean(
//            name = {"casServletContainerFactory"}
//    )
//    @Bean
//    public EmbeddedServletContainerFactory casServletContainerFactory() {
//        return new CasTomcatEmbeddedServletContainerFactory(this.casProperties.getServer().getClustering());
//    }
//
//    @ConditionalOnMissingBean(
//            name = {"casTomcatEmbeddedServletContainerCustomizer"}
//    )
//    @Bean
//    public EmbeddedServletContainerCustomizer casTomcatEmbeddedServletContainerCustomizer() {
//        return (configurableEmbeddedServletContainer) -> {
//            if (configurableEmbeddedServletContainer instanceof TomcatEmbeddedServletContainerFactory) {
//                TomcatEmbeddedServletContainerFactory tomcat = (TomcatEmbeddedServletContainerFactory)configurableEmbeddedServletContainer;
//                this.configureAjp(tomcat);
//                this.configureHttp(tomcat);
//                this.configureHttpProxy(tomcat);
//                this.configureExtendedAccessLogValve(tomcat);
//                this.configureRewriteValve(tomcat);
//                this.configureSSLValve(tomcat);
//                this.configureBasicAuthn(tomcat);
//            } else {
//                LOGGER.error("EmbeddedServletContainer [{}] does not support Tomcat!", configurableEmbeddedServletContainer);
//            }
//
//        };
//    }
//
//    private void configureBasicAuthn(final TomcatEmbeddedServletContainerFactory tomcat) {
//        CasEmbeddedApacheTomcatBasicAuthenticationProperties basic = this.casProperties.getServer().getBasicAuthn();
//        if (basic.isEnabled()) {
//            tomcat.addContextCustomizers(new TomcatContextCustomizer[]{(ctx) -> {
//                LoginConfig config = new LoginConfig();
//                config.setAuthMethod("BASIC");
//                ctx.setLoginConfig(config);
//                List var10000 = basic.getSecurityRoles();
//                Objects.requireNonNull(ctx);
//                var10000.forEach(ctx::addSecurityRole);
//                basic.getAuthRoles().forEach((r) -> {
//                    SecurityConstraint constraint = new SecurityConstraint();
//                    constraint.addAuthRole(r);
//                    SecurityCollection collection = new SecurityCollection();
//                    List var10000 = basic.getPatterns();
//                    Objects.requireNonNull(collection);
//                    var10000.forEach(collection::addPattern);
//                    constraint.addCollection(collection);
//                    ctx.addConstraint(constraint);
//                });
//            }});
//            tomcat.addContextValves(new Valve[]{new BasicAuthenticator()});
//        }
//
//    }
//
//    private void configureRewriteValve(final TomcatEmbeddedServletContainerFactory tomcat) {
//        final Resource res = this.casProperties.getServer().getRewriteValve().getLocation();
//        if (ResourceUtils.doesResourceExist(res)) {
//            LOGGER.debug("Configuring rewrite valve at [{}]", res);
//            RewriteValve valve = new RewriteValve() {
//                protected synchronized void startInternal() {
//                    try {
//                        super.startInternal();
//                        InputStream is = res.getInputStream();
//                        Throwable var2 = null;
//
//                        try {
//                            InputStreamReader isr = new InputStreamReader(is, StandardCharsets.UTF_8);
//                            Throwable var4 = null;
//
//                            try {
//                                BufferedReader buffer = new BufferedReader(isr);
//                                Throwable var6 = null;
//
//                                try {
//                                    this.parse(buffer);
//                                } catch (Throwable var32) {
//                                    var6 = var32;
//                                    throw var32;
//                                } finally {
//                                    $closeResource(var6, buffer);
//                                }
//                            } catch (Throwable var34) {
//                                var4 = var34;
//                                throw var34;
//                            } finally {
//                                $closeResource(var4, isr);
//                            }
//                        } catch (Throwable var36) {
//                            var2 = var36;
//                            throw var36;
//                        } finally {
//                            if (is != null) {
//                                $closeResource(var2, is);
//                            }
//
//                        }
//
//                    } catch (Throwable var38) {
//                        throw var38;
//                    }
//                }
//            };
//            valve.setAsyncSupported(true);
//            valve.setEnabled(true);
//            LOGGER.debug("Creating Rewrite valve configuration for the embedded tomcat container...");
//            tomcat.addContextValves(new Valve[]{valve});
//        }
//
//    }
//
//    private void configureExtendedAccessLogValve(final TomcatEmbeddedServletContainerFactory tomcat) {
//        CasEmbeddedApacheTomcatExtendedAccessLogProperties ext = this.casProperties.getServer().getExtAccessLog();
//        if (ext.isEnabled() && StringUtils.isNotBlank(ext.getPattern())) {
//            LOGGER.debug("Creating extended access log valve configuration for the embedded tomcat container...");
//            ExtendedAccessLogValve valve = new ExtendedAccessLogValve();
//            valve.setPattern(ext.getPattern());
//            if (StringUtils.isBlank(ext.getDirectory())) {
//                valve.setDirectory(this.serverProperties.getTomcat().getAccesslog().getDirectory());
//            } else {
//                valve.setDirectory(ext.getDirectory());
//            }
//
//            valve.setPrefix(ext.getPrefix());
//            valve.setSuffix(ext.getSuffix());
//            valve.setAsyncSupported(true);
//            valve.setEnabled(true);
//            valve.setRotatable(true);
//            valve.setBuffered(true);
//            tomcat.addContextValves(new Valve[]{valve});
//            tomcat.addEngineValves(new Valve[]{valve});
//        }
//
//    }
//
//    private void configureHttp(final TomcatEmbeddedServletContainerFactory tomcat) {
//        CasEmbeddedApacheTomcatHttpProperties http = this.casProperties.getServer().getHttp();
//        if (http.isEnabled()) {
//            LOGGER.debug("Creating HTTP configuration for the embedded tomcat container...");
//            Connector connector = new Connector(http.getProtocol());
//            int port = http.getPort();
//            if (port <= 0) {
//                LOGGER.warn("No explicit port configuration is provided to CAS. Scanning for available ports...");
//                port = SocketUtils.findAvailableTcpPort();
//            }
//
//            LOGGER.info("Activated embedded tomcat container HTTP port on [{}]", port);
//            connector.setPort(port);
//            LOGGER.debug("Configuring embedded tomcat container for HTTP2 protocol support");
//            connector.addUpgradeProtocol(new Http2Protocol());
//            Map var10000 = http.getAttributes();
//            Objects.requireNonNull(connector);
//            var10000.forEach(connector::setAttribute);
//            tomcat.addAdditionalTomcatConnectors(new Connector[]{connector});
//        }
//
//    }
//
//    private void configureHttpProxy(final TomcatEmbeddedServletContainerFactory tomcat) {
//        CasEmbeddedApacheTomcatHttpProxyProperties proxy = this.casProperties.getServer().getHttpProxy();
//        if (proxy.isEnabled()) {
//            LOGGER.debug("Customizing HTTP proxying for connector listening on port [{}]", tomcat.getPort());
//            tomcat.getTomcatConnectorCustomizers().add((connector) -> {
//                connector.setSecure(proxy.isSecure());
//                connector.setScheme(proxy.getScheme());
//                if (StringUtils.isNotBlank(proxy.getProtocol())) {
//                    LOGGER.debug("Setting HTTP proxying protocol to [{}]", proxy.getProtocol());
//                    connector.setProtocol(proxy.getProtocol());
//                }
//
//                if (proxy.getRedirectPort() > 0) {
//                    LOGGER.debug("Setting HTTP proxying redirect port to [{}]", proxy.getRedirectPort());
//                    connector.setRedirectPort(proxy.getRedirectPort());
//                }
//
//                if (proxy.getProxyPort() > 0) {
//                    LOGGER.debug("Setting HTTP proxying proxy port to [{}]", proxy.getProxyPort());
//                    connector.setProxyPort(proxy.getProxyPort());
//                }
//
//                connector.addUpgradeProtocol(new Http2Protocol());
//                Map var10000 = proxy.getAttributes();
//                Objects.requireNonNull(connector);
//                var10000.forEach(connector::setAttribute);
//                LOGGER.info("Configured connector listening on port [{}]", tomcat.getPort());
//            });
//        } else {
//            LOGGER.debug("HTTP proxying is not enabled for CAS; Connector configuration for port [{}] is not modified.", tomcat.getPort());
//        }
//
//    }
//
//    private void configureAjp(final TomcatEmbeddedServletContainerFactory tomcat) {
//        CasEmbeddedApacheTomcatAjpProperties ajp = this.casProperties.getServer().getAjp();
//        if (ajp.isEnabled() && ajp.getPort() > 0) {
//            LOGGER.debug("Creating AJP configuration for the embedded tomcat container...");
//            Connector ajpConnector = new Connector(ajp.getProtocol());
//            ajpConnector.setProtocol(ajp.getProtocol());
//            ajpConnector.setPort(ajp.getPort());
//            ajpConnector.setSecure(ajp.isSecure());
//            ajpConnector.setAllowTrace(ajp.isAllowTrace());
//            ajpConnector.setScheme(ajp.getScheme());
//            ajpConnector.setAsyncTimeout(Beans.newDuration(ajp.getAsyncTimeout()).toMillis());
//            ajpConnector.setEnableLookups(ajp.isEnableLookups());
//            ajpConnector.setMaxPostSize(ajp.getMaxPostSize());
//            ajpConnector.addUpgradeProtocol(new Http2Protocol());
//            if (ajp.getProxyPort() > 0) {
//                LOGGER.debug("Set AJP proxy port to [{}]", ajp.getProxyPort());
//                ajpConnector.setProxyPort(ajp.getProxyPort());
//            }
//
//            if (ajp.getRedirectPort() > 0) {
//                LOGGER.debug("Set AJP redirect port to [{}]", ajp.getRedirectPort());
//                ajpConnector.setRedirectPort(ajp.getRedirectPort());
//            }
//
//            Map var10000 = ajp.getAttributes();
//            Objects.requireNonNull(ajpConnector);
//            var10000.forEach(ajpConnector::setAttribute);
//            tomcat.addAdditionalTomcatConnectors(new Connector[]{ajpConnector});
//        }
//
//    }
//
//    private void configureSSLValve(final TomcatEmbeddedServletContainerFactory tomcat) {
//        CasEmbeddedApacheTomcatSslValveProperties valveConfig = this.casProperties.getServer().getSslValve();
//        if (valveConfig.isEnabled()) {
//            LOGGER.debug("Adding SSLValve to context of the embedded tomcat container...");
//            SSLValve valve = new SSLValve();
//            valve.setSslCipherHeader(valveConfig.getSslCipherHeader());
//            valve.setSslCipherUserKeySizeHeader(valveConfig.getSslCipherUserKeySizeHeader());
//            valve.setSslClientCertHeader(valveConfig.getSslClientCertHeader());
//            valve.setSslSessionIdHeader(valveConfig.getSslSessionIdHeader());
//            tomcat.addContextValves(new Valve[]{valve});
//        }
//
//    }
//}
//
